package com.socialin.android.hackaton.draw;

import java.io.IOException;
import java.util.ArrayList;

import org.json.JSONException;
import org.json.JSONObject;

import android.os.Build;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.HandlerThread;
import android.os.Message;

import com.clwillingham.socket.io.IOSocket;
import com.clwillingham.socket.io.MessageCallback;
import com.socialin.android.L;
import com.socialin.android.hackaton.draw.listener.JsonReceiver;

public class MessageQueue implements Callback {
	
	public static final int STATUS_DISCONNECTED = -1;
	public static final int STATUS_CONNECTED = 0;
	public static final int STATUS_PENDING = 1;
	
	private volatile int status = STATUS_DISCONNECTED;
	private IOSocket socket;
	
	private static MessageQueue insatnce;
	
	private static final int MSG_CONNECT = 1;
	private static final int MSG_SEND_MSG = 2;
	
	Handler handler = new Handler(this);
	Handler uiHandler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			if(msg.what == 1){
				drawingReceiver.onReceive((JSONObject) msg.obj);
			}else if(msg.what == 2){
				chatReceiver.onReceive((JSONObject) msg.obj);
			}
		}
	};
	
	ArrayList<String> msgQueue = new ArrayList<String>(100);
	
	JsonReceiver drawingReceiver;
	JsonReceiver chatReceiver;
	
	
	
	private MessageQueue(){
		HandlerThread hThread = new HandlerThread("MessageQueue thread");
		hThread.start();
		handler = new Handler(hThread.getLooper(), this);
		connect();
		
	}
	
	public static MessageQueue getInstance(){
		if(insatnce == null){
			insatnce = new MessageQueue();
		}
		return insatnce;
	}
	
	public void setDrawingReceiver(JsonReceiver val){
		drawingReceiver = val;
	}
	public void setChatReceiver(JsonReceiver val){
		chatReceiver = val;
	}
	
	public int getStatus(){
		return status;
	}
	
	public void sendMessage(String msg){
		Message message = handler.obtainMessage(MSG_SEND_MSG);
		message.obj = msg;
		handler.sendMessage(message);
	}
	
	private void sendMessageSync(String msg){
		if(status == STATUS_CONNECTED){
			try {
//				while(msgQueue.size() > 0){
//					socket.send(msgQueue.get(0));
//					msgQueue.remove(0);
//				}
				socket.send(msg);
			} catch (IOException e) {
				e.printStackTrace();
				msgQueue.add(msg);
			}
		}
	}
	
	private void connect(){
		handler.sendEmptyMessage(MSG_CONNECT);
	}
	
	public void connectSync() {
		if(status != STATUS_DISCONNECTED)
			return;
		status = STATUS_PENDING;
		try {
			socket = new IOSocket("http://192.168.122.102:80", new MessageCallback() {
				@Override
				public void on(String event, JSONObject... data) {
					// Handle events
					L.d("on");
				}

				@Override
				public void onMessage(String message) {
					// Handle simple messages
					L.d("onMessage:" + message);
					try {
						JSONObject msgJsonObj = new JSONObject(message);
						String action = msgJsonObj.getString("action");
						Message uiMsg = uiHandler.obtainMessage();
						if(action.equals("draw")){
							uiMsg.what = 1;
							uiMsg.obj = msgJsonObj;
//							drawingReceiver.onReceive(msgJsonObj);
						}else if(action.equals("message")){
							uiMsg.what = 2;
							uiMsg.obj = msgJsonObj;
//							chatReceiver.onReceive(msgJsonObj);
						}
						uiHandler.sendMessage(uiMsg);
					} catch (JSONException e) {
						e.printStackTrace();
					}
				}

				@Override
				public void onMessage(JSONObject message) {
					// Handle JSON messages
					L.d("onMessage JSONObject");
				}

				@Override
				public void onConnect() {
					// Socket connection opened
					L.d("onMessage onConnect");
					status = STATUS_CONNECTED;
//					try {
//						JSONObject handshake = new JSONObject();
//						handshake.put("action", "init");
//						socket.send(handshake.toString());
//					} catch (IOException e) {
//						e.printStackTrace();
//					} catch (JSONException e) {
//						e.printStackTrace();
//					}
				}

				@Override
				public void onDisconnect() {
					// Socket connection closed
					L.d("onDisconnect");
					status = STATUS_DISCONNECTED;
				}
			});
			socket.connect();
		} catch (Exception e) {
			e.printStackTrace();
			status = STATUS_DISCONNECTED;
		}

	}

	@Override
	public boolean handleMessage(Message msg) {
		switch (msg.what) {
		case MSG_CONNECT:
			L.d("MSG_CONNECT");
			connectSync();
			break;
		case MSG_SEND_MSG:
			L.d("MSG_SEND_MSG");
			if(status != STATUS_CONNECTED)
				connectSync();
			sendMessageSync((String) msg.obj);
		}
		return true;
	}

}
